package neves.android.etmg.tilemap;

import java.util.LinkedList;

import android.app.AlertDialog;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import neves.android.etmg.GameCore;
import neves.android.etmg.R;
import neves.android.etmg.pathfinding.AStarSearchWithBSP_TileMap;
import neves.android.etmg.sprite.BaseController;
import neves.android.etmg.sprite.Creature;
import neves.android.etmg.sprite.CreatureControl;
import neves.android.etmg.sprite.GameItem;
import neves.android.etmg.sprite.GameSprite;
import neves.android.etmg.sprite.MovableObject;
import neves.android.etmg.sprite.SpriteType;
import neves.android.etmg.sprite.action.GameAction;
import neves.android.etmg.tilemap.mapcreater.TileMapCreater;
import neves.android.etmg.tilemap.mapcreater.TileMapCreater_MultiRoom;
import neves.android.etmg.tilemap.objects.Stair;

public class TileGameCore extends GameCore {

	protected GameAction moveUp;
	protected GameAction moveDown;
	protected GameAction moveLeft;
	protected GameAction moveRight;
	protected GameAction padCenter;

	protected Creature player;
	
	protected CreatureControl mobControl;

	protected TileMapRender tileMapRender;

	protected TileMapCreater tileMapCreater;

	protected boolean isRoundBase = true;
	
	protected boolean[] askToNextFloor = new boolean[]{false};

	public TileGameCore(SurfaceHolder surfaceHolder, Context context,
			Handler handler) {
		super(surfaceHolder, context, handler);
		// TODO Auto-generated constructor stub

		/** map creater **/
		tileMapCreater = new TileMapCreater_MultiRoom();//new TileMapCreater_TwoBigRoom();

		/** input manager **/
		TileInputManager tileInputAgent = new TileInputManager();

		SetInputManager(tileInputAgent);

		CreateGameActions();

		/** AI Controler **/
		mobControl = new BaseController();

		/** player initial **/
		player = new Creature("playerA", 10, 10, 0, 0, SpriteType.CreatureType);

		player.SetImage(BitmapFactory.decodeResource(context.getResources(),
				R.drawable.block_red));

		/** map render initial **/
		tileMapRender = new TileMapRender();

		CreateNewTileMap();

	}

	public void CreateGameActions() {

		moveUp = new GameAction("moveUp", GameAction.DETECT_INITAL_PRESS_ONLY);
		moveDown = new GameAction("moveDown",
				GameAction.DETECT_INITAL_PRESS_ONLY);
		moveLeft = new GameAction("moveLeft",
				GameAction.DETECT_INITAL_PRESS_ONLY);
		moveRight = new GameAction("moveRight",
				GameAction.DETECT_INITAL_PRESS_ONLY);
		padCenter = new GameAction("padCenter",
				GameAction.DETECT_INITAL_PRESS_ONLY);

		inputAgent.MapToKey(moveUp, android.view.KeyEvent.KEYCODE_DPAD_UP);
		inputAgent.MapToKey(moveDown, android.view.KeyEvent.KEYCODE_DPAD_DOWN);
		inputAgent.MapToKey(moveLeft, android.view.KeyEvent.KEYCODE_DPAD_LEFT);
		inputAgent
				.MapToKey(moveRight, android.view.KeyEvent.KEYCODE_DPAD_RIGHT);
		inputAgent.MapToKey(padCenter,
				android.view.KeyEvent.KEYCODE_DPAD_CENTER);
	}

	@Override
	public void run() {

		while (isRunning) {
			Canvas c = null;
			try {
				c = mainSurfaceHolder.lockCanvas(null);

				CheckInput();

				synchronized (mainSurfaceHolder) {
					if (currentMode == STATE_RUNNING) {

						UpdatePhysics();

						if (currentMap.GetMapRender() != null) {
							currentMap.GetMapRender().DoDraw(c);
						}

						// if(isRoundBase) currentMode = STATE_PAUSE;

					}

					// mapRender.DoDraw(c);

				}
			} finally {
				// do this in a finally so that if an exception is thrown
				// during the above, we don't leave the Surface in an
				// inconsistent state
				if (c != null) {
					mainSurfaceHolder.unlockCanvasAndPost(c);
				}
			}
		}
	}

	// protected boolean doKeyDown(int keyCode, KeyEvent msg) {
	// synchronized (mainSurfaceHolder) {
	//			
	// if(inputAgent!=null){
	// inputAgent.onKeyDown(keyCode, msg);
	// }
	//				
	// return false;
	// }
	// }

	public void CheckInput() {
		synchronized (mainSurfaceHolder) {

			if (moveUp.isPressed()) {
				moveUp.release();

				player.SetShift(0, -1);

				if ((currentMode == STATE_READY)) {
					// ready-to-start -> start
					doStart();
					// return true;
				} else if (currentMode == STATE_PAUSE) {
					// paused -> running
					// unpause();
					// return true;
				} else {

				}
			}
			if (moveDown.isPressed()) {
				moveDown.release();

				player.SetShift(0, 1);

			}

			if (moveLeft.isPressed()) {
				moveLeft.release();

				player.SetShift(-1, 0);
				// doStart();
			}

			if (moveRight.isPressed()) {
				moveRight.release();

				player.SetShift(1, 0);
			}

			if (padCenter.isPressed()) {
				padCenter.release();
				CreateNewTileMap();
				
				//AStarSearchWithBSP_TileMap pathSeer = new AStarSearchWithBSP_TileMap((TileMap)this.currentMap);
				
				//MovableObject moba = this.currentMap.GetCreatures().getFirst();
				
				//int[] locaa = moba.GetPos();
				
				//pathSeer.find(moba,this.player);

			}
		}

	}

	protected void UpdatePhysics() {

		// player move phase
		boolean isPlayerActioned = TryToAction(player);
		
		if (isPlayerActioned) {

			AIMove();

			/**  try to move mobs **/
			for (GameSprite sprite : currentMap.GetSprites()) {

				TryToAction(sprite);

				// Log.w("ETMG",sprite.GetType()+" [ "+nextPos[0]+" "+nextPos[1]+"] "+((TileMap)currentMap).GetIntTile(nextPos[0],
				// nextPos[1]) );

			}

			int[] ppos = player.GetPos();
	
			currentMap.GetViewer().SetPos(ppos[0], ppos[1]);

			/**  check item on step **/
			int[] itempos = null;
			for (GameItem curItem : currentMap.GetItems()) {
				itempos = curItem.GetPos();
				if( ppos[0] == itempos[0] && ppos[1] == itempos[1]){
					curItem.Action_StepOn();
					Log.w("ETMG","on Item!"+askToNextFloor[0]);
				}
				// Log.w("ETMG",sprite.GetType()+" [ "+nextPos[0]+" "+nextPos[1]+"] "+((TileMap)currentMap).GetIntTile(nextPos[0],
				// nextPos[1]) );

			}
			
			// if step on stair
			if(askToNextFloor[0]){
				
                //Message msg = messageHandler.obtainMessage();
                //Bundle b = new Bundle();
                //b.putString("text", "To next floor.");
                //b.putInt("viz", View.VISIBLE);
                //msg.setData(b);
                //messageHandler.sendMessage(msg);
				askToNextFloor[0] = false;
				setState(this.STATE_PAUSE,null);
				
				
			}
			
		}
		
		//showNextStairDialog(); 		
			
		
		
	}

	

	
	protected boolean TryToAction(GameSprite sprite) {

		if (sprite.HasMoveDemend()) {
			int[] nextPos = sprite.GetUpdatedPos();

			if (!((TileMap) currentMap).isLegalPos(nextPos[0], nextPos[1], sprite.GetType())) {
				sprite.SetShift(0, 0);
				return false;
			} else {

				sprite.Update();
				return true;
			}
		}
		return false;
	}

	protected void AIMove() {

		LinkedList<Creature> creatures = currentMap.GetCreatures();

		for (Creature curMob : creatures) {
			//Log.w("ETMG", "Action!" + curMob.GetName());
			mobControl.NextMove(currentMap, player, curMob);
		}

	}

	protected void CreateNewTileMap() {

		TileMap tileMap = tileMapCreater.CreateMap();

		tileMap.SetMapRender(tileMapRender);

		/** player **/
		tileMap.SetPlayer(player);

		int[] ppos = tileMap.RandomRoomRandomPos();

		player.SetPos(ppos[0], ppos[1]);

		/** stair **/
		Stair stair = new Stair("stair", SpriteType.ItemType, askToNextFloor);

		int[] stairPos = tileMap.RandomRoomRandomPos();

		stair.SetPos(stairPos[0], stairPos[1]);
			
		tileMap.AddItem(stair);
			
		
		/** temMob **/
		Creature mobA = new Creature("MobA", 20, 20, 1, 1,
				SpriteType.CreatureType);
		int[] newPos = tileMap.RandomRoomRandomPos();
		mobA.SetPos(newPos[0], newPos[1]);
		tileMap.AddCreature(mobA);

		SetMap(tileMap);
	}
}
